﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Collections;
using System.Json;
using Fleck;

namespace SpaceShooterServer
{
    class Program
    {
        const int GAMEPLAYERS = 1;

        static void Main(string[] args)
        {
            int id = 1000;
            var ran = new Random();
            var allSockets = new Hashtable();
            var server = new WebSocketServer("ws://localhost:8080");
            var timer = new Timer(40);
            var ticks = 0;
            var gameRunning = false;

            server.Start(socket =>
            {
                #region Connection Opened

                socket.OnOpen = () =>
                {
                    if (gameRunning)
                    {
                        socket.Close();
                        return;
                    }

                    var ship = id;
                    var ships = new JsonArray();
                    var json = new JsonObject();
                    json["added"] = new JsonArray(ship);
                    var message = json.ToString();

                    foreach (IWebSocketConnection s in allSockets.Keys)
                    {
                        s.Send(message);
                        ships.Add((int)allSockets[s]);
                    }

                    allSockets.Add(socket, id++);
                    json["added"] = ships;
                    socket.Send(json.ToString());

                    if (allSockets.Count == GAMEPLAYERS)
                    {
                        timer.Start();
                        gameRunning = true;
                        json = new JsonObject();
                        json["status"] = new JsonObject();
                        json["status"]["x"] = ran.Next(0, 800);
                        json["status"]["y"] = ran.Next(0, 600);
                        message = json.ToString();

                        foreach (IWebSocketConnection s in allSockets.Keys)
                            s.Send(message);
                    }
                };

                #endregion

                #region Connection Closed

                socket.OnClose = () =>
                {
                    var json = new JsonObject();
                    var ship = (int)allSockets[socket];
                    allSockets.Remove(socket);
                    json["removed"] = ship;
                    var message = json.ToString();

                    foreach (IWebSocketConnection s in allSockets.Keys)
                        s.Send(message);

                    if (allSockets.Count == 0)
                    {
                        gameRunning = false;
                        timer.Stop();
                        ticks = 0;
                    }
                };

                #endregion

                #region Message Sent

                socket.OnMessage = message =>
                {
                    var json = new JsonObject();
                    json["logic"] = JsonObject.Parse(message);
                    json["logic"]["ship"]["id"] = (int)allSockets[socket];
                    var back = json.ToString();
                    
                    foreach (IWebSocketConnection s in allSockets.Keys)
                        if(s != socket)
                            s.Send(back);
                };

                #endregion
            });

            timer.Elapsed += new ElapsedEventHandler((sender, e) =>
            {
                #region Server Generated Items

                var json = new JsonObject();

                if (ticks % 100 == 0)
                    json["asteroid"] = Helpers.GenerateAsteroid();

                if (json.Keys.Count > 0)
                {
                    var message = json.ToString();

                    foreach (IWebSocketConnection s in allSockets.Keys)
                        s.Send(message);
                }

                ticks++;

                #endregion
            });

            var input = Console.ReadLine();
            timer.Close();
            timer.Dispose();
            server.Dispose();
        }
    }
}
